﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace MultiVolumeControl.Core
{
	public delegate void HotKeyEventHandler(object sender, HotKeyEventArgs e);
	
	public class HotKeyCatcher : NativeWindow, IDisposable
	{
		private int counter;
		private IDictionary<string,string> keyMap;
		
		public event HotKeyEventHandler HotKeyPressed;
		
		public HotKeyCatcher(){
			CreateHandle(new CreateParams());
			keyMap=new Dictionary<string,string>();
		}
		
		protected override void WndProc(ref Message m)
		{
			base.WndProc(ref m);
			if (m.Msg != Win32Utils.WM_HOTKEY)
				return;
			Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
			ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);
			if(HotKeyPressed==null)
				return;
			HotKeyPressed(this, new HotKeyEventArgs(keyMap[modifier+"/"+key], modifier, key));
		}

		public bool Register(string name, Tuple<ModifierKeys,Keys> tuple)
		{
			if(tuple == null)
				return false;
			return Register(name, tuple.Item1, tuple.Item2);
		}
		
		public bool Register(string name, ModifierKeys modifier, Keys key)
		{
			Interlocked.Increment(ref counter);
			if(Win32Utils.RegisterHotKey(this, counter, modifier, key)){
				keyMap[modifier+"/"+key] = name;
				return true;
			}
			return false;
		}
		
		public void UnregisterAll(){
			for(int i=1; i<=counter; i++)
				Win32Utils.UnregisterHotKey(this, i);
		}
		
		public void Dispose()
		{
			UnregisterAll();
			DestroyHandle();
		}
	}
	
	public struct HotKeyEventArgs
	{
		private readonly string name;
		private readonly ModifierKeys modifier;
		private readonly Keys key;
		
		public HotKeyEventArgs(string name, ModifierKeys modifier, Keys key) {
			this.name=name;
			this.modifier=modifier;
			this.key=key;
		}

		public string Name { get { return name; } }
		public ModifierKeys Modifier { get { return modifier; } }
		public Keys Key { get { return key; } }
	}
}